home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1994 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee,
- * provided that (i) the above copyright notices and this permission
- * notice appear in all copies of the software and related documentation,
- * and (ii) the name of Silicon Graphics may not be used in any
- * advertising or publicity relating to the software without the specific,
- * prior written permission of Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL,
- * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
- * OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
- /*
- * lens - Roam around a very large image using textures tiles.
- *
- * Demonstrates the use of subtexture and texture color table extensions.
- *
- * $Revision: 1.1 $
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <bstring.h>
- #include <math.h>
- #include <GL/glu.h>
- #include <GL/gl.h>
- #include <GL/glx.h>
- #include <X11/keysym.h>
- #include <gl/image.h>
- #include "xwindow.h"
- #include "util.h"
-
- #if !defined(GL_EXT_subtexture) || !defined(GL_EXT_abgr)
- BOTH EXT_subtexture and EXT_abgr must be defined
- #else
-
-
- /* set to 1 for debug.. slower, but includes error checking */
- #define DEBUG 0
-
- /* a word the size of 4 bytes (e.g. an RGBA pixel) */
- typedef unsigned int u_int32;
-
- typedef struct tileimg {
- int xsize, ysize;
- int xtiles, ytiles;
- int tilexsize, tileysize;
- u_int32 **tiles;
- } tileimg;
-
- tileimg *img = NULL;
-
- #define GETTILE(IMG,TX,TY) ((IMG)->tiles[(TY)*(IMG)->xtiles+(TX)])
-
- #define MAXWIDTH (4*4096)
-
- /* size of the physical texture */
- #define TEX_SIZE_S 1024
- #define TEX_SIZE_T 1024
-
- int Lminx = -TEX_SIZE_S;
- int Lmaxx = -TEX_SIZE_S;
- int Lminy = -TEX_SIZE_T;
- int Lmaxy = -TEX_SIZE_T;
-
- unsigned int tileXSize = 64;
- unsigned int tileYSize = 64;
-
- long winxsize, winysize;
- int xorg, yorg;
-
- float myangle = 0;
- float zoom = 1;
- GLboolean useTct;
-
- u_int32 *bgdtile = NULL;
- Display *dpy;
- Window win;
-
- tileimg *readTiles();
- void changeTct(void);
- void changeModel(void);
- void rgbToPackedRgba(unsigned short *rbuf, unsigned short *gbuf,
- unsigned short *bbuf, u_int32 *lbuf,int xsize);
- void processEvents(void);
- void makeMesh0(float x0, float x1, float y0, float y1,
- float s0, float s1, float t0, float t1, float z, int nx,int ny);
- void makeMesh1(float x0, float x1, float y0, float y1,
- float s0, float s1, float t0, float t1, float z, int nx,int ny);
- void makeMesh2(float x0, float x1, float y0, float y1,
- float s0, float s1, float t0, float t1, float z, int nx,int ny);
- void makeMesh3(float x0, float x1, float y0, float y1,
- float s0, float s1, float t0, float t1, float z, int nx,int ny);
- void makeTable1(void);
- void makeTable2(void);
- void makeTable3(void);
- void makeTable4(void);
-
- void drawTiles(tileimg *img, int xorg, int yorg, int winxsize, int winysize);
- void makeRgbBgdTile(void);
- void makeRgbaBgdTile(void);
- void applyRgbaBgd(tileimg *img);
- tileimg *readTiles(IMAGE *image, int tilexsize, int tileysize);
-
- #if DEBUG
- void chkError(char *msg);
- #else
- #define chkError
- #endif
- void usage(char *name, int exitStatus);
-
- void
- printHelp(void)
- {
- printf("\tUp/Down arrow - zoom in/out\n"
- "\tl - cycle through texture lookup tables\n"
- "\tw - cycle through warping effects\n"
- "\tLeft mouse - drag image\n"
- "\tMiddle/Right mouse - rotate image CCW/CW\n"
- "\th/? - help\n"
- "\tEsc - quit\n");
- }
-
- void
- main(int argc, char **argv)
- {
- GLXContext ctx;
- int visualAttr[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, None};
-
- if (argc < 2)
- usage(argv[0], EXIT_FAILURE);
- if (argv[1][0] == '-' && argv[1][1] == 'h')
- usage(argv[0], EXIT_SUCCESS);
-
- winxsize = winysize = 768;
- createWindowAndContext(&dpy, &win, &ctx, 0, 0, winxsize, winysize,
- GL_TRUE, NULL, visualAttr, "lens");
- /* Change the event mask to watch for motion and button release as well */
- XSelectInput(dpy,win, ExposureMask | StructureNotifyMask | KeyPressMask |
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
- XFlush(dpy);
- glClear(GL_COLOR_BUFFER_BIT);
- glXSwapBuffers(dpy, win);
-
- /*
- * check for required extensions.
- * we know an RE/REC/REV with "abgr" has limited "subtexture" support,
- * but doesn't advertise it.
- */
- if (!QueryExtension("GL_EXT_subtexture") &&
- (strncmp("RE",glGetString(GL_RENDERER),2) ||
- !QueryExtension("GL_EXT_abgr"))) {
-
- fprintf(stderr,"Sorry, EXT_subtexture required.. trying anyway.\n");
- #if 0
- exit(EXIT_FAILURE);
- #endif
- }
-
- #if defined(GL_SGI_texture_color_table)
- if (!(useTct = QueryExtension("GL_SGI_texture_color_table"))) {
- /*
- * HACK - texture color table may not be formally advertised.
- * Try using it anyhow.
- */
- glDisable(GL_TEXTURE_COLOR_TABLE_SGI);
- if (glGetError() == GL_NO_ERROR) {
- fprintf(stderr,
- "Assuming SGI_texture_color_table supported but not advertised\n");
- useTct = GL_TRUE;
- }
- } else
- useTct = GL_TRUE;
- if (!useTct)
- fprintf(stderr,
- "SGI_texture_color_table is not supported by this renderer\n");
- #else
- useTct = GL_FALSE;
- #endif
-
- {
- IMAGE *image = iopen(argv[1], "r");
- int iclose(IMAGE *);
-
- if (!image) {
- fprintf(stderr,"%s: can't open input file %s\n",argv[0], argv[1]);
- exit(EXIT_FAILURE);
- }
- if (argc > 2) {
- tileXSize = atoi(argv[2]);
- tileYSize = argc > 3 ? atoi(argv[3]) : tileXSize;
- }
- fprintf(stderr,"TILE{XSIZE, YSIZE} = %d,%d\n",tileXSize,tileYSize);
- img = readTiles(image, tileXSize, tileYSize);
- (void) iclose(image);
- }
-
- makeRgbaBgdTile();
- applyRgbaBgd(img);
-
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glTranslatef(0.5,0.5,0.0);
- glScalef(.61,.61,1.);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- gluPerspective(90.,1.,.1,10.);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.,0.,-1.5);
-
- glEnable(GL_TEXTURE_2D);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); /*default*/
- glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); /*default*/
-
- glTexImage2D(GL_TEXTURE_2D,0,GL_RGB5_EXT,TEX_SIZE_S,TEX_SIZE_T,0,
- GL_RGBA,GL_UNSIGNED_BYTE,NULL);
- #if DEBUG
- chkError("after glTexImage2D");
- #endif
-
- xorg = -(img->xsize/2.0 - TEX_SIZE_S/2.0);
- yorg = -(img->ysize/2.0 - TEX_SIZE_T/2.0);
-
- makeMesh0(-1.5,1.5,-1.5,1.5,0.0,1.0,0.0,1.0,0.0,64,64);
-
- drawTiles(img,-xorg,-yorg,winxsize,winysize);
- glXSwapBuffers(dpy, win);
-
- chkError("before processEvents");
-
- printHelp();
-
- processEvents();
- }
-
- void
- usage(char *name, int exitStatus)
- {
- fprintf(stderr,
- "usage: %s [-h (for help)] inimage [[tileWidthAndHeight] or\
- [tileWidth tileHeight]]\n", name);
- fprintf(stderr,
- "\tInteractively, `h/?' keys provide description of interface\n");
- exit(exitStatus);
- }
-
- void
- processEvents(void)
- {
- int lx, ly, mx, my;
- float fx, fy;
- int i;
- int leftdown = 0;
-
- while(1) {
- int needredraw;
- XEvent event;
- XNextEvent(dpy, &event);
- switch (event.type) {
- case Expose: /* window needs to be redrawn */
- {
- /* skip all but last "Expose" event (X often sends 2 or 3) */
- if (((XExposeEvent*) &event)->count == 0) {
- drawTiles(img,-xorg,-yorg,winxsize,winysize);
- glXSwapBuffers(dpy, win);
- }
- }
- break;
- case ConfigureNotify: /* window resize (or a move) occurred */
- {
- winxsize = ((XConfigureEvent*) &event)->width;
- winysize = ((XConfigureEvent*)&event)->height;
- glViewport(0, 0, winxsize, winysize);
- drawTiles(img,-xorg,-yorg,winxsize,winysize);
- glXSwapBuffers(dpy, win);
- }
- break;
- case KeyPress:
- {
- KeySym keysym;
-
- (void) XLookupString(&event.xkey, NULL, 0, &keysym, 0);
- switch (keysym) {
- case XK_Escape: /* ESC key */
- exit(EXIT_SUCCESS);
- break;
- case XK_Up: /* up arrow */
- zoom -= .02;
- if (zoom < 0.02) zoom = 0.02;
- drawTiles(img,-xorg,-yorg,winxsize,winysize);
- glXSwapBuffers(dpy, win);
- break;
- case XK_Down: /* down arrow */
- zoom += .02;
- if (zoom > 1) zoom = 1;
- drawTiles(img,-xorg,-yorg,winxsize,winysize);
- glXSwapBuffers(dpy, win);
- break;
- case XK_w:
- changeModel();
- drawTiles(img,-xorg,-yorg,winxsize,winysize);
- glXSwapBuffers(dpy, win);
- break;
- case XK_l: /* left arrow */
- changeTct();
- chkError("after changeTct");
- drawTiles(img,-xorg,-yorg,winxsize,winysize);
- glXSwapBuffers(dpy, win);
- break;
- case XK_h:
- case XK_H:
- case XK_question:
- printHelp();
- break;
- }
- }
- break;
- case ButtonPress:
- {
- switch (((XButtonEvent *)&event)->button) {
- case 1:
- leftdown = 1;
- lx = ((XButtonEvent *)&event)->x;
- ly = ((XButtonEvent *)&event)->y;
- break;
- case 2:
- do {
- myangle -= 1.0;
- if (myangle < -360.0)
- myangle += 360.0;
- drawTiles(img, -xorg, -yorg, winxsize, winysize);
- glXSwapBuffers(dpy, win);
- } while(xGetButton(2, dpy, win));
- break;
- case 3:
- do {
- myangle += 1.0;
- if (myangle > 360.0)
- myangle -= 360.0;
- drawTiles(img,-xorg,-yorg,winxsize,winysize);
- glXSwapBuffers(dpy, win);
- } while (xGetButton(3, dpy, win));
- break;
- }
- }
- break;
-
- case MotionNotify: /* cursor moved (in window) */
- /* absorb extra motion events... */
- if (leftdown) {
- XMotionEvent *ev = (XMotionEvent*)&event;
-
- while (XEventsQueued(dpy, QueuedAfterReading)) {
- XEvent tev;
-
- XNextEvent(dpy, &tev);
- if (tev.type == MotionNotify) {
- ev = (XMotionEvent*)&tev;
- } else {
- XPutBackEvent(dpy, &tev);
- break;
- }
- }
- mx = ev->x;
- my = ev->y;
- if(mx != lx || my != ly) {
- xorg += (mx - lx);
- yorg += -(my - ly); /* in X, y is inverted (yuk) */
- drawTiles(img, -xorg, -yorg, winxsize, winysize);
- glXSwapBuffers(dpy, win);
- lx = mx;
- ly = my;
- }
- }
- break;
- case ButtonRelease:
- if (((XButtonEvent *)&event)->button == 1)
- leftdown = 0;
- break;
- }
- #if DEBUG
- chkError("processEvents");
- #endif
- }
- }
-
-
- void
- changeModel(void)
- {
- static int model = 0;
-
- model = (model + 1) % 4;
- switch (model) {
- case 0:
- makeMesh0(-1.5,1.5,-1.5,1.5,0.0,1.0,0.0,1.0,0.0,64,64);
- break;
- case 1:
- makeMesh1(-1.5,1.5,-1.5,1.5,0.0,1.0,0.0,1.0,0.0,64,64);
- break;
- case 2:
- makeMesh3(-1.5,1.5,-1.5,1.5,0.0,1.0,0.0,1.0,0.0,64,64);
- break;
- case 3:
- makeMesh2(-1.5,1.5,-1.5,1.5,0.0,1.0,0.0,1.0,0.0,64,64);
- break;
- }
- }
-
- tileimg *
- readTiles(IMAGE *image, int tilexsize, int tileysize)
- {
- int xsize, ysize, zsize;
- int i, x, y, ntiles;
- u_int32 *lptr;
- u_int32 ***tiles;
- tileimg *img;
- unsigned short rbuf[MAXWIDTH];
- unsigned short gbuf[MAXWIDTH];
- unsigned short bbuf[MAXWIDTH];
- u_int32 lbuf[MAXWIDTH];
-
-
- xsize = image->xsize;
- ysize = image->ysize;
- zsize = image->zsize;
-
- if (image->xsize > MAXWIDTH) {
- printf("cannot handle image wider than %d pixels.\n", MAXWIDTH);
- exit(EXIT_FAILURE);
- }
-
- img = (tileimg *) malloc(sizeof(tileimg));
- img->xsize = xsize;
- img->ysize = ysize;
- img->xtiles = ((xsize-1)/tilexsize)+1;
- img->ytiles = ((ysize-1)/tileysize)+1;
- img->tilexsize = tilexsize;
- img->tileysize = tileysize;
- img->tiles =
- (u_int32**) malloc(img->ytiles*img->xtiles * sizeof(u_int32*));
- ntiles = img->xtiles*img->ytiles;
- #if DEBUG
- printf("begin malloc ntile %d size %d\n",ntiles,tilexsize*tileysize*4);
- printf("\t\t tilexsize,tileysize: %d %d xsize,ysize %d %d xtiles\
- ytiles:%d %d\n", tilexsize,tileysize,xsize,ysize,img->xtiles,img->ytiles);
- #endif
- for(i=0; i<ntiles; i++) {
- img->tiles[i] =
- (u_int32 *) malloc(tilexsize*tileysize*sizeof(u_int32));
- }
- #if DEBUG
- printf("end malloc\n");
- #endif
- printf("Reading image..."); fflush(stdout);
- for(y=0; y<ysize; y++) {
- int getrow(IMAGE *image, unsigned short *buffer,
- unsigned int y, unsigned int z);
- if(zsize >= 3) {
- getrow(image,rbuf,y,0);
- getrow(image,gbuf,y,1);
- getrow(image,bbuf,y,2);
- rgbToPackedRgba(rbuf,gbuf,bbuf,lbuf,xsize);
- } else {
- getrow(image,rbuf,y,0);
- rgbToPackedRgba(rbuf,rbuf,rbuf,lbuf,xsize);
- }
- for(x=0; x<img->xtiles; x++) {
- lptr = GETTILE(img,x,y/tileysize) + (tilexsize*(y%tileysize));
- bcopy(lbuf+x*tilexsize,lptr,tilexsize*sizeof(u_int32));
- }
- }
- printf("Done\n"); fflush(stdout);
- return img;
- }
-
- /*
- * The following 4 procedures create meshes for the different kind of
- * warping effects.
- */
- #define MAXMESH 64
-
- float Ml[4*2*(MAXMESH+1)*2 * (MAXMESH+1)];
-
- void
- makeMesh0(float x0, float x1, float y0, float y1,
- float s0, float s1, float t0, float t1, float z, int nx,int ny)
- {
- float y,x,s,t,dx,dy,ds,dt,vb[3],tb[2];
- float v;
- float *mp = Ml;
-
- dx = (x1-x0)/nx;
- dy = (y1-y0)/ny;
- ds = (s1-s0)/nx;
- dt = (t1-t0)/ny;
- y = y0;
- t = t0;
- vb[2] = z;
- while (y < y1) {
- x = x0;
- s = s0;
- while(x <= x1) {
- tb[0] = s; tb[1] = t;
- vb[0] = x; vb[1] = y;
- vb[2] = 0.0;
- *mp++ = tb[0];
- *mp++ = tb[1];
- mp += 2;
- *mp++ = vb[0];
- *mp++ = vb[1];
- *mp++ = vb[2];
- mp++;
- tb[1] = t+dt;
- vb[1] = y+dy;
- vb[2] = 0.0;
- *mp++ = tb[0];
- *mp++ = tb[1];
- mp += 2;
- *mp++ = vb[0];
- *mp++ = vb[1];
- *mp++ = vb[2];
- mp++;
- x += dx;
- s += ds;
- }
- y += dy;
- t += dt;
- }
- }
-
- void
- makeMesh1(float x0, float x1, float y0, float y1,
- float s0, float s1, float t0, float t1, float z, int nx, int ny)
- {
- float y,x,s,t,dx,dy,ds,dt,vb[3],tb[2];
- float v;
- float *mp = Ml;
- float N = 2.0;
- float B = -1.5;
-
- dx = (x1-x0)/nx;
- dy = (y1-y0)/ny;
- ds = (s1-s0)/nx;
- dt = (t1-t0)/ny;
- y = y0;
- t = t0;
- vb[2] = z;
- while (y < y1) {
- x = x0;
- s = s0;
- while(x <= x1) {
- tb[0] = s; tb[1] = t;
- vb[0] = x; vb[1] = y;
- v = N*N - x*x - y*y;
- if (v < 0.0) v = 0.0;
- vb[2] = sqrt(v) + B;
- if (vb[2] < 0.) vb[2] = 0.0;
- *mp++ = tb[0];
- *mp++ = tb[1];
- mp += 2;
- *mp++ = vb[0];
- *mp++ = vb[1];
- *mp++ = vb[2];
- mp++;
- tb[1] = t+dt;
- vb[1] = y+dy;
- v = N*N - x*x - (y+dy)*(y+dy);
- if (v < 0.0) v = 0.0;
- vb[2] = sqrt(v) + B;
- if (vb[2] < 0.) vb[2] = 0.0;
- *mp++ = tb[0];
- *mp++ = tb[1];
- mp += 2;
- *mp++ = vb[0];
- *mp++ = vb[1];
- *mp++ = vb[2];
- mp++;
- x += dx;
- s += ds;
- }
- y += dy;
- t += dt;
- }
- }
-
- void
- makeMesh2(float x0, float x1, float y0, float y1,
- float s0, float s1, float t0, float t1, float z, int nx,int ny)
- {
- float y,x,s,t,dx,dy,ds,dt,vb[3],tb[2];
- float v;
- float *mp = Ml;
- float N2 = 4.0;
- float B2 = -3.5;
-
- dx = (x1-x0)/nx;
- dy = (y1-y0)/ny;
- ds = (s1-s0)/nx;
- dt = (t1-t0)/ny;
- y = y0;
- t = t0;
- vb[2] = z;
- while (y < y1) {
- x = x0;
- s = s0;
- while(x <= x1) {
- tb[0] = s; tb[1] = t;
- vb[0] = x; vb[1] = y;
- v = N2*N2 - x*x - y*y;
- if (v < 0.0) v = 0.0;
- vb[2] = sqrt(v) + B2;
- *mp++ = tb[0];
- *mp++ = tb[1];
- mp += 2;
- *mp++ = vb[0];
- *mp++ = vb[1];
- *mp++ = vb[2];
- mp++;
- tb[1] = t+dt;
- vb[1] = y+dy;
- v = N2*N2 - x*x - (y+dy)*(y+dy);
- if (v < 0.0) v = 0.0;
- vb[2] = sqrt(v) + B2;
- *mp++ = tb[0];
- *mp++ = tb[1];
- mp += 2;
- *mp++ = vb[0];
- *mp++ = vb[1];
- *mp++ = vb[2];
- mp++;
- x += dx;
- s += ds;
- }
- y += dy;
- t += dt;
- }
- }
-
- void
- makeMesh3(float x0, float x1, float y0, float y1,
- float s0, float s1, float t0, float t1, float z, int nx, int ny)
- {
- float y,x,s,t,dx,dy,ds,dt,vb[3],tb[2];
- float v;
- float *mp = Ml;
- float N3 = 2.0;
- float B3 = -1.0;
-
- dx = (x1-x0)/nx;
- dy = (y1-y0)/ny;
- ds = (s1-s0)/nx;
- dt = (t1-t0)/ny;
- y = y0;
- t = t0;
- vb[2] = z;
- while (y < y1) {
- x = x0;
- s = s0;
- while(x <= x1) {
- tb[0] = s; tb[1] = t;
- vb[0] = x; vb[1] = y;
- v = N3*N3 - x*x - y*y;
- if (v < 0.0) v = 0.0;
- vb[2] = sqrt(v) + B3;
- if (vb[2] < 0.) vb[2] = 0.0;
- vb[2] = -vb[2];
- *mp++ = tb[0];
- *mp++ = tb[1];
- mp += 2;
- *mp++ = vb[0];
- *mp++ = vb[1];
- *mp++ = vb[2];
- mp++;
- tb[1] = t+dt;
- vb[1] = y+dy;
- v = N3*N3 - x*x - (y+dy)*(y+dy);
- if (v < 0.0) v = 0.0;
- vb[2] = sqrt(v) + B3;
- if (vb[2] < 0.) vb[2] = 0.0;
- vb[2] = -vb[2];
- *mp++ = tb[0];
- *mp++ = tb[1];
- mp += 2;
- *mp++ = vb[0];
- *mp++ = vb[1];
- *mp++ = vb[2];
- mp++;
- x += dx;
- s += ds;
- }
- y += dy;
- t += dt;
- }
- }
-
- void
- drawMesh(int nx,int ny)
- {
- float *mp = Ml;
- int i,j;
-
- glColor4f(1,1,1,1);
- for (i = ny+1; i; i--) {
- glBegin(GL_TRIANGLE_STRIP);
- for (j = nx+1; j; j--) {
- glTexCoord2fv(mp); mp += 4;
- glVertex3fv(mp); mp += 4;
- glTexCoord2fv(mp); mp += 4;
- glVertex3fv(mp); mp += 4;
- }
- glEnd();
- }
- }
-
-
- void
- loadtile(float s, float t, int x, int y, tileimg *img)
- {
- GLvoid *tile;
-
- tile = (GLvoid *) (x < 0 || x >= img->xtiles || y < 0 || y >= img->ytiles ?
- bgdtile : GETTILE(img,x,y));
- glTexSubImage2DEXT(GL_TEXTURE_2D, 0, s*TEX_SIZE_S+.5, t*TEX_SIZE_T+.5,
- tileXSize, tileYSize, GL_RGBA, GL_UNSIGNED_BYTE,
- tile);
- #if DEBUG
- chkError("after glTexSubImage2D");
- #endif
- }
-
- void
- drawTiles(tileimg *img, int xorg, int yorg, int winxsize, int winysize)
- {
- int minx,maxx,miny,maxy;
- float s0,t0;
- int x, y, first,last;
-
- glClear(GL_COLOR_BUFFER_BIT);
-
- minx = xorg < 0 ? (xorg - img->tilexsize - 1)/img->tilexsize :
- xorg/img->tilexsize;
- maxx = (xorg + TEX_SIZE_S)/(float) img->tilexsize - 1;
- miny = yorg < 0 ? (yorg-img->tileysize-1)/img->tileysize :
- yorg/img->tileysize;
- maxy = (yorg + TEX_SIZE_T)/(float) img->tileysize - 1;
-
- /* Bring in any newly exposed tiles on the left */
- if (minx < Lminx) {
- for (x = minx; x < Lminx; x++) {
- s0 = x * (tileXSize/(float) TEX_SIZE_S);
- s0 -= (int) s0; /* get the fractional position */
- if (s0 < 0.0)
- s0 += 1.0;
- for (y = miny; y <= maxy; y++) {
- t0 = y * (tileYSize/(float) TEX_SIZE_T);
- t0 -= (int) t0;
- if (t0 < 0.0)
- t0 += 1.0;
- loadtile(s0, t0, x, y, img);
-
- }
- }
- first = Lminx;
- } else
- first = minx;
-
- /* Bring in newly exposed tiles on the right */
- if (maxx > Lmaxx) {
- x = Lmaxx > minx ? Lmaxx+1 : minx;
- last = x - 1;
- for (; x <= maxx; x++) {
- s0 = x * (tileXSize/(float) TEX_SIZE_S);
- s0 -= (int) s0; /* get the fractional position */
- if (s0 < 0.0)
- s0 += 1.0;
- for (y = miny; y <= maxy; y++) {
- t0 = y * (tileYSize/(float) TEX_SIZE_T);
- t0 -= (int) t0;
- if (t0 < 0.0)
- t0 += 1.0;
- loadtile(s0, t0, x, y, img);
- }
- }
- } else
- last = maxx;
-
- /* Bring in newly exposed tiles on the bottom */
- if (miny < Lminy) {
- for (y = miny; y < Lminy; y++) {
- t0 = y * (tileYSize/(float) TEX_SIZE_T);
- t0 -= (int) t0; /* get the fractional position */
- if (t0 < 0.0)
- t0 += 1.0;
- for (x = first; x <= last; x++) {
- s0 = x * (tileXSize/(float) TEX_SIZE_S);
- s0 -= (int) s0; /* get the fractional position */
- if (s0 < 0.0)
- s0 += 1.0;
- loadtile(s0, t0, x, y, img);
- }
- }
- }
-
- /* Bring in newly exposed tiles on the top */
- if (maxy > Lmaxy) {
- for (y = Lmaxy+1 ; y <= maxy; y++) {
- t0 = y * (tileYSize/(float) TEX_SIZE_T);
- t0 -= (int) t0; /* get the fractional position */
- if (t0 < 0.0)
- t0 += 1.0;
- for (x = first; x <= last; x++) {
- s0 = x * (tileXSize/(float) TEX_SIZE_S);
- s0 -= (int) s0; /* get the fractional position */
- if (s0 < 0.0)
- s0 += 1.0;
- loadtile(s0, t0, x, y, img);
- }
- }
- }
-
- Lminx = minx;
- Lmaxx = maxx;
- Lminy = miny;
- Lmaxy = maxy;
- glMatrixMode(GL_TEXTURE);
- glLoadIdentity();
- glTranslatef(xorg/(float) TEX_SIZE_S+0.5,yorg/(float) TEX_SIZE_T+0.5,0.0);
- glRotatef(myangle, 0, 0, 1); /* z rotate */
- glScalef(.63*zoom,.63*zoom,1.);
- glTranslatef(-.5,-.5,0.);
- glMatrixMode(GL_MODELVIEW);
-
- drawMesh(64,64);
- }
-
-
- void
- changeTct(void)
- {
- static int lut = 0;
-
- if (!useTct) {
- fprintf(stderr, "SGI_texture_color_table is not supported\n");
- return;
- }
-
- #if defined(GL_SGI_texture_color_table)
-
- lut = (lut + 1) % 5;
- if (lut == 0) {
- glDisable(GL_TEXTURE_COLOR_TABLE_SGI);
- chkError("after disable TCT");
- return;
- }
- glEnable(GL_TEXTURE_COLOR_TABLE_SGI);
- chkError("after enable TCT");
-
- switch (lut) {
- case 1: makeTable1(); break;
- case 2: makeTable2(); break;
- case 3: makeTable3(); break;
- case 4: makeTable4(); break;
- }
- #endif
- }
-
- void
- makeTable1(void)
- {
- #if defined(GL_SGI_texture_color_table)
- static unsigned long table[256];
- static int done = 0;
- int i;
- float v;
- int iv;
-
- if (!done) {
- for (i = 0; i < 256; i++){
- v = i/255.0;
- iv = powf(v,(float) 2.0) * 255;
- table[i] = ((iv)<<24) | ((iv)<<16) | ((iv)<<8) | ((iv));
- }
- done = 1;
- }
-
- glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI, GL_RGBA8_EXT, 256,
- GL_RGBA, GL_UNSIGNED_BYTE, table);
- #endif
- }
-
- void
- makeTable2(void)
- {
- #if defined(GL_SGI_texture_color_table)
- static unsigned long table[256];
- static int done = 0;
- int i;
- float v;
- int iv;
-
- if (!done) {
- for (i = 0; i < 256; i++) {
- v = i/255.0;
- iv = powf(v,(float) 1.0) * 255;
- table[i] = ((iv)<<24) | ((iv)<<16) | ((iv)<<8) | ((iv));
- }
- done = 1;
- }
-
- glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI, GL_RGBA8_EXT, 256,
- GL_RGBA, GL_UNSIGNED_BYTE, table);
- #endif
- }
-
-
- /*
- * define DLIST first time, and call it every time.
- */
- void
- makeTable3(void)
- {
- #if defined(GL_SGI_texture_color_table)
- static unsigned long table[256];
- static GLuint list = 0;
- int i;
- float v;
- int iv;
-
- if (list == 0) {
- for (i = 0; i < 256; i++){
- v = i/255.0;
- iv = powf(v,(float) 0.5) * 255;
- table[i] = ((iv)<<24) | ((iv)<<16) | ((iv)<<8) | ((iv));
- }
- list = glGenLists(1);
- glNewList(list, GL_COMPILE);
- glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI, GL_RGBA8_EXT, 256,
- GL_RGBA, GL_UNSIGNED_BYTE, table);
- glEndList();
- }
-
- glCallList(list);
- #endif
- }
-
- /*
- * Create an inverting color table ("negative" effect)
- * use LUMINANCE table because R,G,B,A tables are the same.
- */
- void
- makeTable4(void)
- {
- #if defined(GL_SGI_texture_color_table)
- static unsigned char table[256];
- static int done = 0;
- int i;
-
- if (!done) {
- for (i = 0; i < 256; i++) {
- table[i] = 255-i;
- }
- done = 1;
- }
- glColorTableSGI(GL_TEXTURE_COLOR_TABLE_SGI, GL_RGBA8_EXT, 256,
- GL_LUMINANCE, GL_UNSIGNED_BYTE, table);
- #endif
- }
-
- void
- rgbToPackedRgba(unsigned short *rbuf, unsigned short *gbuf,
- unsigned short *bbuf, u_int32 *lbuf, int xsize)
- {
- char *cptr;
- int i;
-
- cptr = (char *) lbuf;
-
- for (i = xsize; i; i--) {
- *cptr++ = *rbuf++;
- *cptr++ = *gbuf++;
- *cptr++ = *bbuf++;
- *cptr++ = 0x00;
- }
- }
-
- /*
- * "Draw" an rgb tile for the background.
- */
- void
- makeRgbBgdTile(void)
- {
- int i,j,grid;
- char *ptr;
-
- bgdtile = (u_int32 *) malloc(tileXSize*tileYSize*sizeof(u_int32)*3/4);
- grid = 8;
- ptr = (char *) bgdtile;
- for (i=0; i<tileYSize; i++) {
- for(j=0; j<tileXSize; j++) {
- if(i%grid == 0 || j%grid == 0) {
- *ptr++ = 0x0; *ptr++ = 0x0; *ptr++ = 0x40;
- } else {
- *ptr++ = 0x40; *ptr++ = 0x40; *ptr++ = 0x40;
- }
- }
- }
- }
-
- /*
- * "Draw" an rgba tile for the background.
- */
- void
- makeRgbaBgdTile(void)
- {
- int i,j,grid;
- u_int32 *ptr;
-
- bgdtile = (u_int32 *) malloc(tileXSize*tileYSize*sizeof(u_int32));
- grid = 8;
- ptr = (u_int32 *) bgdtile;
- for (i=0; i<tileYSize; i++) {
- for(j=0; j<tileXSize; j++) {
- if(i%grid == 0 || j%grid == 0) {
- *ptr++ = 0x40000000; /* red is the upper byte */
- } else {
- *ptr++ = 0x40404000;
- }
- }
- }
- }
-
- void
- applyBgd(tileimg *img)
- {
- int extras,y,x,i,j;
- char *ptr,*bgd;
-
- extras = img->xsize % img->tilexsize;
- if (extras) {
- for (y=0; y< img->ytiles; y++) {
- ptr = (char *) GETTILE(img,img->xtiles-1,y);
- bgd = (char *) bgdtile;
- for (j = 0; j< img->tileysize; j++) {
- ptr += 3*extras;
- bgd += 3*extras;
- for (i=extras; i< img->tilexsize; i++) {
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- }
- }
- }
- }
- extras = img->ysize % img->tileysize;
- if (extras) {
- for (x=0; x< img->xtiles; x++) {
- ptr = (char *) GETTILE(img,x,img->ytiles-1);
- bgd = (char *) bgdtile;
- ptr += 3*extras* img->tilexsize;
- bgd += 3*extras* img->tilexsize;
- for (j = extras; j< img->tileysize; j++) {
- for (i=0; i< img->tilexsize; i++) {
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- }
- }
- }
- }
- }
-
- void
- applyRgbaBgd(tileimg *img)
- {
- int extras,y,x,i,j;
- char *ptr,*bgd;
-
- extras = img->xsize % img->tilexsize;
- if (extras) {
- for (y=0; y< img->ytiles; y++) {
- ptr = (char *) GETTILE(img,img->xtiles-1,y);
- bgd = (char *) bgdtile;
- for (j = 0; j< img->tileysize; j++) {
- ptr += 4*extras;
- bgd += 4*extras;
- for (i=extras; i< img->tilexsize; i++) {
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- }
- }
- }
- }
- extras = img->ysize % img->tileysize;
- if (extras) {
- for (x=0; x< img->xtiles; x++) {
- ptr = (char *) GETTILE(img,x,img->ytiles-1);
- bgd = (char *) bgdtile;
- ptr += 4*extras* img->tilexsize;
- bgd += 4*extras* img->tilexsize;
- for (j = extras; j< img->tileysize; j++) {
- for (i=0; i< img->tilexsize; i++) {
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- *ptr++ = *bgd++;
- }
- }
- }
- }
- }
-
- #if DEBUG
- void
- chkError(char *msg)
- {
- GLenum err;
- char *errstr;
-
- while ((err = glGetError()) != GL_NO_ERROR) {
- fprintf(stderr,
- "ERROR: %s: glGetError returned %s (expected GL_NO_ERROR)\n",
- msg, gluErrorString(err));
- }
- }
- #endif
- #endif /* defined on extensions (else part) */
-